#include "Client.h"

using namespace std;
using namespace net;

/**
 * Client::init()
 *
 * Description
 *     Init initializes the client to the given ip address of the server,
 *     it initializes the virtual UDP connection
 *
 * Paramaters
 *     None
 *
 * Returns
 *     Node id on success, -1 on failure
 */
int Client::init(){
    pNode_ = new Node(PROTOCOLID, SENDRATE, TIMEOUT);
    if (!InitializeSockets())
        throw "failed to initialize sockets";
    if (!pNode_->Start(0)) 
        throw "failed to start pNode_";
    pNode_->Join(Address(ip_[0],ip_[1],ip_[2],ip_[3],MESHPORT));
    isConnected_ = false;
    for (int i = 0; i < 100; i++){
        if (pNode_->IsConnected())
            return pNode_->GetLocalNodeId();
        else {
            pNode_->Update(DELTATIME);
            wait_seconds(DELTATIME);
        }
    }
    return -1;
}

/**
 * void Client::sendpacket(const unsigned char* inpacket)
 * 
 * Description
 *     Sends an unsigned char packet to the server
 *
 * Parameters
 *     const unsigned char* inpacket is the string you wish to send
 *
 * Return value
 *     void
 */
void Client::sendpacket(const unsigned char* inpacket){
    if (pNode_->IsConnected()) {
        if (!isConnected_) {
            isConnected_ = true;
            cout << "is connected as client " << pNode_->GetLocalNodeId() << endl;
        }
        pNode_->SendPacket(0, inpacket, 256);
    }
    else
        cout << "Connecting...\n";
    pNode_->Update(DELTATIME);
    wait_seconds(DELTATIME);
}

/**
 * void Client::receivepacket(unsigned char* packet)
 * 
 * Description
 *     Waits for a packet from the server
 *
 * Parameters
 *     unsigned char* packet which the received data gets passed into
 * 
 * Return value
 *     void
 */
void Client::receivepacket(unsigned char* packet){
    while (true) {
        int nodeId = -1;
        int bytes_read = pNode_->ReceivePacket(nodeId, packet, 256);
        if (bytes_read == 0){
            break;
        }
        assert(nodeId == 0);
    }
}

/**
 * void Client::shutdown()
 *
 * Description
 *     Shuts down the sockets being used by the client
 *
 * Parameters
 *     none
 *
 * Return Value
 *     void
 */
void Client::shutdown(){
    ShutdownSockets();
}

/**
 * cpVect Client::stringToVect(const unsigned char* in)
 *
 * Description
 *     This translates a string to a cpVect
 *
 * Parameters
 *     const unsigned char* input string, with two floats seperated
 *         by spaces
 *
 * Return Value
 *     cpVect of the translated coordinates
 */
cpVect Client::stringToVect(const unsigned char* in){
    string s((const char*)in);
    istringstream iss(s);
    float first, second;
    iss >> first >> second;
    cpVect v;
    v.x = first;
    v.y = second;
    return v;
}



